/*
 * Copyright (c) 2009, D. Adam Karim <adam@akarsoft.com>
 * 
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#import <ObjCurses/OCWindow.h>


@implementation OCWindow

@synthesize window;
@synthesize parent;
@synthesize subWindows;
@synthesize siblings;
@synthesize backgroundColor;

- (id)init
{
	if ((self = [super init])) {
		[self initializer];
		window = stdscr;
	}
	
	return self;
}

- (id)initWithWindow:(WINDOW *)win
{
	if ((self = [super init])) {
		[self initializer];
		window = win ? win : stdscr;
	}
	
	return self;
}

- (id)initWithParent:(OCWindow *)win
			location:(NSRect)location
			absolute:(BOOL)absolute;
{
	if ((self = [super init])) {
		int height = location.size.height;
		int width = location.size.width;
		int x = location.origin.x;
		int y = location.origin.y;
		
		[self initializer];
		
		if (absolute) {
			x -= getbegx([win window]);
			y -= getbegy([win window]);
		}
		
		window = derwin([win window],
						height,
						width,
						y,
						x);
		
		[self setParent:win];
		siblings = [win subWindows];
		[[win subWindows] addObject:self];
	}
	
	return self;
}

- (void)dealloc
{
	endwin();
	
	[super dealloc];
}

- (void)initializer
{
	subWindows = [NSMutableArray array];
	(void)initscr();
	(void)noecho();
	(void)cbreak();
	[self setKeyboard];
}

- (void)deleteSubWindow:(OCWindow *)subWindow
{
	werase([subWindow window]);
	delwin([subWindow window]);
}

- (int)length
{
	return LINES;
}

- (int)width
{
	return COLS;
}

- (void)clear
{
	clear();
}

- (void)refresh
{
	refresh();
}

- (int)printToWindow:(NSString *)format,...
{
	va_list arguments;
	va_start(arguments, format);
	int result = [self printToWindowWithFormat:format
									 arguments:arguments];
	va_end(arguments);
	return result;
}

- (int)printToWindowAtPoint:(NSPoint)point
					 format:(NSString *)format,...
{
	va_list arguments;
	va_start(arguments, format);
	int result = [self printToWindowAtPoint:point
									 format:format
								  arguments:arguments];
	va_end(arguments);
	return result;
}

- (int)printToWindowWithFormat:(NSString *)format
					 arguments:(va_list)arguments
{
	NSString *output = [[NSString alloc] initWithFormat:format
											  arguments:arguments];
	int result = wprintw(window, [output UTF8String]);
	[output release];
	return result;
}

- (int)printToWindowAtPoint:(NSPoint)point
					 format:(NSString *)format
				  arguments:(va_list)arguments
{
	int result = wmove(window, point.y, point.x);
	if (result == OK) {
		NSString *output = [[NSString alloc] initWithFormat:format
												  arguments:arguments];
		result = wprintw(window, [output UTF8String]);
		[output release];
	}
	return result;
}

- (int)scanFromWindow:(NSString *)format,...;
{
	va_list arguments;
	va_start(arguments, format);
	int result = [self scanFromWindowWithFormat:format
									  arguments:arguments];
	va_end(arguments);
	return result;
}

- (int)scanFromWindowAtPoint:(NSPoint)point
					  format:(NSString *)format,...
{
	va_list arguments;
	va_start(arguments, format);
	int result = [self scanFromWindowAtPoint:point
									  format:format
								   arguments:arguments];
	va_end(arguments);
	return result;
}

- (int)scanFromWindowWithFormat:(NSString *)format
					  arguments:(va_list)arguments
{
	int result = ERR;
	result = vw_scanw(window, (char *)[format UTF8String], arguments);
	return result;
}

- (int)scanFromWindowAtPoint:(NSPoint)point
					  format:(NSString *)format
				   arguments:(va_list)arguments
{
	int result = ERR;
	
	if ((wmove(window, point.y, point.x)) != ERR)
		result = vw_scanw(window, (char *)[format UTF8String], arguments);
	
	return result;
}

- (void)setKeyboard
{
	keypad(window, TRUE);
	meta(window, TRUE);
}

- (BOOL)useColors
{
	if (has_colors()) {
		start_color();
		hasColors = YES;
		return YES;
	}
	
	return NO;
}

- (void)setColorPair:(OCColorPair)pair
{
	if (hasColors) {
		init_pair(pair.pair,
				  pair.foreground,
				  pair.background);
	}
}

- (void)setBackgroundColor:(int)pair
{
	if (hasColors) {
		backgroundColor = pair;
		wbkgd(window, COLOR_PAIR(pair));
	}
}

- (void)box
{
	box(window, 0, 0);
}
							   
@end

OCColorPair
OCMakeColorPair(int pair, int foreground, int background)
{
	return (OCColorPair){pair, foreground, background};
}